package org.TUApp.eTour;

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
	import android.database.Cursor;
	import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
	import android.database.sqlite.SQLiteQueryBuilder;
	import android.net.Uri;
import android.text.TextUtils;


/**
 * This data provider contains static informations about campus locations' geographical information, bus stops, informations, history.
 * @author Hui Liu
 */
	public class CampusMapData extends ContentProvider {

        /**
         * The log tag.
         */
        private static final String TAG = CampusMapData.class.getSimpleName();

        /**
         * The content provider authority as described in the AndroidManifest.
         */
        public static final String AUTHORITY = Constant.PKG;

        private TUeTourDBHelper dbHelper;

        //The underlying database
  	  private SQLiteDatabase tourMapDB;

  	  // table names
  	  private static final String T_LOCATION = "locations";
  	  private static final String T_ROUTES = "route";
  	  private static final String T_DEPARTMENTS = "departments";


  	  // Column Names
  	  public static final String KEY_ID = "_id";
  	  public static final String KEY_NAME = "name";
  	  public static final String KEY_LOCATION_LAT = "latitude";
  	  public static final String KEY_LOCATION_LNG = "longitude";
  	  public static final String KEY_LTYPE = "ltype";
  	  public static final String KEY_DETAILS = "details";
  	  public static final String KEY_HISTORY = "history";
  	  public static final String KEY_RINDEX = "rIndex";
  	  public static final String KEY_PHOTO = "photo";
  	  public static final String KEY_LID = "locationID";
//  	  public static final String KEY_LINK = "link";
  	  public static final String KEY_STOP_ID = T_LOCATION+ "._id";
  	  public static final String KEY_ROUTE_ID = T_ROUTES+ "._id";

  	  private static final String STOPS_JOIN = T_LOCATION + " JOIN " + T_ROUTES +
  	  	" ON " + T_LOCATION +".rIndex = " + T_ROUTES + "." + KEY_ID;

  	  // Column indexes
  	  public static final int NAME_COLUMN = 1;
  	  public static final int LATITUDE_COLUMN = 2;
  	  public static final int LONGITUDE_COLUMN = 3;
  	  public static final int LTYPE_COLUMN = 4;
  	  public static final int DETAILS_COLUMN = 5;
  	  public static final int HISTORY_COLUMN = 6;
  	  public static final int RINDEX_COLUMN = 7;
  	  public static final int PHOTO_COLUMN = 8;
 	  public static final int ROUTE_COLUMN = 10;
 	  public static final int ROUTE_SHORT_COLUMN = 11;

 	  public static final int DEPT_LINK_COLUMN = 4;
	  
	  // Create the constants used to differentiate between the different URI 
	  // requests.
	  private static final int LOCATION = 1;
	  private static final int LOCATION_ID = 2;
	  private static final int LOCATION_TYPE = 3;
	  private static final int LOCATION_SEARCH = 4;
	  private static final int STOP = 5;
	  private static final int STOP_ID = 6;
	  private static final int DEPARTMENTS = 7;
	  private static final int DEPARTMENTS_LID = 8;
	  private static final int ROUTES = 10;
	  private static final int ROUTE_ID = 11;
	  private static final int SEARCH = 9;
	  
	  

	  private static final UriMatcher uriMatcher;

	  // Allocate the UriMatcher object, where a URI ending in 'locations' will
	  // correspond to a request for all locations, and 'locations' with a 
	  // trailing '/[rowID]' will represent a single location row.
	  static {
	   uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	   uriMatcher.addURI(AUTHORITY, "locations", LOCATION);
	   uriMatcher.addURI(AUTHORITY, "locations/#", LOCATION_ID);
	   uriMatcher.addURI(AUTHORITY, "locations/*/ltype", LOCATION_TYPE); // all locations ltype = *
	   uriMatcher.addURI(AUTHORITY, "locations/search/*", LOCATION_SEARCH);
	   uriMatcher.addURI(AUTHORITY, "stops/", STOP);
	   uriMatcher.addURI(AUTHORITY, "stops/#", STOP_ID);
	   uriMatcher.addURI(AUTHORITY, "routes/", ROUTES);
	   uriMatcher.addURI(AUTHORITY, "routes/#", ROUTE_ID);
	   uriMatcher.addURI(AUTHORITY, "departments", DEPARTMENTS);
	   uriMatcher.addURI(AUTHORITY, "departments/#", DEPARTMENTS_LID); //all departments where locationID=#
	   uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH);
	   uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH);

	  }
	  
      public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/locations");
      public static final Uri STOP_URI = Uri.parse("content://" + AUTHORITY + "/stops");
      public static final Uri VISITOR_PARKING_URI = Uri.parse("content://" + AUTHORITY + "/visitor_parkings");

	  @Override
	  public boolean onCreate() {
          MyLog.v(TAG, "onCreate()");
          return true;
	  }
	    
	  @Override
	  public Cursor query(Uri uri, 
	                      String[] projection, 
	                      String selection, 
	                      String[] selectionArgs, 
	                      String sort) {
	        
	    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
	    String limit = null;
	    qb.setTables(T_LOCATION); //by default is location table

	    // If this is a row query, limit the result set to the passed in row. 
	    switch (uriMatcher.match(uri)) {
	      case LOCATION_ID: 
	    	  qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
	          break;
		    case LOCATION_TYPE: // all locations with given type
		    	qb.appendWhere(KEY_LTYPE + "='" + uri.getPathSegments().get(1) + "'");
		    	break;
		    case LOCATION_SEARCH: //search location by name
	            MyLog.v(TAG, "query>LOCATION_SEARCH");
	            if (!TextUtils.isEmpty(uri.getPathSegments().get(2))) {
	                    qb.appendWhere(KEY_NAME + " LIKE '%" + uri.getPathSegments().get(2) + "%'" );
	            }
	    		break;
		    case DEPARTMENTS: 
		    	qb.setTables(T_DEPARTMENTS);
			    qb.appendWhere(KEY_LTYPE + "='" + uri.getPathSegments().get(1) + "'");
		    	break;
		    case DEPARTMENTS_LID: 	//All departments with given locationID 
		    	qb.setTables(T_DEPARTMENTS);
		    	qb.appendWhere(T_DEPARTMENTS + "." + KEY_LID + "=" + uri.getPathSegments().get(1));
		    	break;
		    case STOP: 
		    	qb.setTables(STOPS_JOIN);
		    	break;
		    case STOP_ID: 
		    	qb.setTables(STOPS_JOIN);
 	    	    qb.appendWhere(KEY_STOP_ID + "=" + uri.getPathSegments().get(1));
		    	break;
		    case ROUTES: 
		    	qb.setTables(T_ROUTES);
		    	break;
		    case ROUTE_ID: 
		    	qb.setTables(STOPS_JOIN);
 	    	    qb.appendWhere(KEY_ROUTE_ID + "=" + uri.getPathSegments().get(1));
		    	break;
		    
	      default      : break;
	    }

	    // If no sort order is specified sort by date / time
	    String orderBy;
	    if (TextUtils.isEmpty(sort)) {
	      orderBy = KEY_ID;
	    } else {
	      orderBy = sort;
	    }

	    // Apply the query to the underlying database.
	    tourMapDB = getDBHelper().getReadableDatabase();
	    Cursor c = qb.query(tourMapDB, projection, selection, selectionArgs, null, null, orderBy, limit);

	    // Register the contexts ContentResolver to be notified if
	    // the cursor result set changes. 
	    c.setNotificationUri(getContext().getContentResolver(), uri);
	    
	    // Return a cursor to the query result.
	    return c;
	  }

	  @Override
	  public Uri insert(Uri _uri, ContentValues _initialValues) {
          MyLog.v(TAG, "insert()");
          MyLog.w(TAG, "The insert method is not available.");
          return null;
/**
          // Insert the new row, will return the row number if 
	    // successful.
	    long rowID = tourMapDB.insert(T_LOCATION, null, _initialValues);
	          
	    // Return a URI to the newly inserted row on success.
	    if (rowID > 0) {
	      Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
	      getContext().getContentResolver().notifyChange(uri, null);
	      return uri;
	    }
	    throw new SQLException("Failed to insert row into " + _uri);
	    */
	  }

	  @Override
	  public int delete(Uri uri, String where, String[] whereArgs) {
          MyLog.v(TAG, "delete()");
          MyLog.w(TAG, "The delete method is not available.");
          return 0;
/**
          int count;
	    
	    switch (uriMatcher.match(uri)) {
	      case LOCATION:
	        count = tourMapDB.delete(T_LOCATION, where, whereArgs);
	        break;

	      case LOCATION_ID:
	        String segment = uri.getPathSegments().get(1);
	        count = tourMapDB.delete(T_LOCATION, KEY_ID + "="
	                                    + segment
	                                    + (!TextUtils.isEmpty(where) ? " AND (" 
	                                    + where + ')' : ""), whereArgs);
	        break;

	      default: throw new IllegalArgumentException("Unsupported URI: " + uri);
	    }

	    getContext().getContentResolver().notifyChange(uri, null);
	    return count;
	    */
	  }

	  @Override
	  /**
	   * not updatable
	   */
	  public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
          MyLog.v(TAG, "update()");
          MyLog.w(TAG, "The update method is not available.");
          return 0;
		  /**
		  int count;
	    switch (uriMatcher.match(uri)) {
	      case LOCATION: count = tourMapDB.update(T_LOCATION, values, 
	                                               where, whereArgs);
	                   break;

	      case LOCATION_ID: String segment = uri.getPathSegments().get(1);
	                     count = tourMapDB.update(T_LOCATION, values, KEY_ID 
	                             + "=" + segment 
	                             + (!TextUtils.isEmpty(where) ? " AND (" 
	                             + where + ')' : ""), whereArgs);
	                     break;

	      default: throw new IllegalArgumentException("Unknown URI " + uri);
	    }

	    getContext().getContentResolver().notifyChange(uri, null);
	    return 0;
	    */
	  }
	  
	  @Override
	  public String getType(Uri uri) {
	    switch (uriMatcher.match(uri)) {
	      case LOCATION: return "vnd.android.cursor.dir/vnd.TUApp.tourMap";
	      case LOCATION_ID: return "vnd.android.cursor.item/vnd.TUApp.tourMap";
	      default: throw new IllegalArgumentException("Unsupported URI: " + uri);
	    }
	  }
      /**
       * @return the database helper
       */
      private SQLiteOpenHelper getDBHelper() {
              if (this.dbHelper == null) {
                      this.dbHelper = new TUeTourDBHelper(getContext());
              }
              return this.dbHelper;
      }
	  

	}